package com.web3.management.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.web3.management.entity.SystemSetting;
import com.web3.management.exception.BusinessException;
import com.web3.management.repository.SystemSettingRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 系统配置服务类
 *
 * @author Web3 Management Team
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SystemSettingService {

    private final SystemSettingRepository systemSettingRepository;
    private final ObjectMapper objectMapper;

    /**
     * 获取所有系统配置
     *
     * @return 配置列表
     */
    public List<SystemSetting> getAllSettings() {
        return systemSettingRepository.findAll();
    }

    /**
     * 根据配置键获取配置
     *
     * @param settingKey 配置键
     * @return 配置信息
     */
    public Optional<SystemSetting> getSettingByKey(String settingKey) {
        return systemSettingRepository.findBySettingKey(settingKey);
    }

    /**
     * 获取配置值并转换为指定类型
     *
     * @param settingKey 配置键
     * @param valueType  值类型
     * @param <T>        泛型类型
     * @return 配置值
     */
    public <T> Optional<T> getSettingValue(String settingKey, Class<T> valueType) {
        Optional<SystemSetting> setting = getSettingByKey(settingKey);

        if (!setting.isPresent()) {
            return Optional.empty();
        }

        try {
            T value = objectMapper.readValue(setting.get().getSettingValue(), valueType);
            return Optional.of(value);
        } catch (JsonProcessingException e) {
            log.error("解析配置值失败: key={}, value={}", settingKey, setting.get().getSettingValue(), e);
            return Optional.empty();
        }
    }

    /**
     * 获取随机休眠配置
     *
     * @return 随机休眠配置
     */
    public Map<String, Object> getRandomSleepConfig() {
        Optional<Map> config = getSettingValue("random_sleep_config", Map.class);
        if (config.isPresent()) {
            return (Map<String, Object>) config.get();
        }

        // 返回默认配置
        Map<String, Object> defaultConfig = new HashMap<>();
        defaultConfig.put("min_seconds", 30);
        defaultConfig.put("max_seconds", 120);
        defaultConfig.put("enabled", true);
        return defaultConfig;
    }

    /**
     * 获取监控配置
     *
     * @return 监控配置
     */
    public Map<String, Object> getMonitorConfig() {
        Optional<Map> config = getSettingValue("monitor_config", Map.class);
        if (config.isPresent()) {
            return (Map<String, Object>) config.get();
        }

        // 返回默认配置
        Map<String, Object> defaultConfig = new HashMap<>();
        defaultConfig.put("enabled", true);
        defaultConfig.put("slippage_threshold", 0.0003);
        return defaultConfig;
    }

    /**
     * 获取通知配置
     *
     * @return 通知配置
     */
    public Map<String, Object> getNotificationConfig() {
        Optional<Map> config = getSettingValue("notification_config", Map.class);
        if (config.isPresent()) {
            return (Map<String, Object>) config.get();
        }

        // 返回默认配置
        Map<String, Object> defaultConfig = new HashMap<>();
        defaultConfig.put("webhook_url", "");
        defaultConfig.put("enabled", true);
        return defaultConfig;
    }

    /**
     * 更新或创建配置
     *
     * @param settingKey   配置键
     * @param settingValue 配置值
     * @param description  配置描述
     * @return 配置信息
     */
    @Transactional
    public SystemSetting updateSetting(String settingKey, Object settingValue, String description) {
        try {
            String jsonValue = objectMapper.writeValueAsString(settingValue);

            Optional<SystemSetting> existingSetting = systemSettingRepository.findBySettingKey(settingKey);

            SystemSetting setting;
            if (existingSetting.isPresent()) {
                // 更新现有配置
                setting = existingSetting.get();
                setting.setSettingValue(jsonValue);
                if (description != null) {
                    setting.setDescription(description);
                }
            } else {
                // 创建新配置
                setting = new SystemSetting();
                setting.setSettingKey(settingKey);
                setting.setSettingValue(jsonValue);
                setting.setDescription(description);
            }

            SystemSetting savedSetting = systemSettingRepository.save(setting);
            log.info("系统配置已更新: key={}, value={}", settingKey, jsonValue);

            return savedSetting;

        } catch (JsonProcessingException e) {
            log.error("序列化配置值失败: key={}, value={}", settingKey, settingValue, e);
            throw new BusinessException("配置值格式错误");
        }
    }

    /**
     * 删除配置
     *
     * @param settingKey 配置键
     */
    @Transactional
    public void deleteSetting(String settingKey) {
        if (!systemSettingRepository.existsBySettingKey(settingKey)) {
            throw new BusinessException("配置不存在: " + settingKey);
        }

        systemSettingRepository.deleteBySettingKey(settingKey);
        log.info("系统配置已删除: key={}", settingKey);
    }

    /**
     * 初始化默认配置
     */
    @Transactional
    public void initializeDefaultSettings() {
        // 随机休眠配置
        if (!systemSettingRepository.existsBySettingKey("random_sleep_config")) {
            Map<String, Object> sleepConfig = new HashMap<>();
            sleepConfig.put("min_seconds", 30);
            sleepConfig.put("max_seconds", 120);
            sleepConfig.put("enabled", true);
            updateSetting("random_sleep_config", sleepConfig, "随机休眠时间配置");
        }

        // 监控配置
        if (!systemSettingRepository.existsBySettingKey("monitor_config")) {
            Map<String, Object> monitorConfig = new HashMap<>();
            monitorConfig.put("enabled", true);
            monitorConfig.put("slippage_threshold", 0.0003);
            updateSetting("monitor_config", monitorConfig, "交易监控配置");
        }

        // 通知配置
        if (!systemSettingRepository.existsBySettingKey("notification_config")) {
            Map<String, Object> notificationConfig = new HashMap<>();
            notificationConfig.put("webhook_url", "");
            notificationConfig.put("enabled", true);
            updateSetting("notification_config", notificationConfig, "异常通知配置");
        }

        log.info("默认系统配置初始化完成");
    }
}